﻿namespace Snipps.Infrastructure
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Windows;

    public class SharedResourceDictionary : ResourceDictionary
    {
#if !DESIGNER
        private static readonly Dictionary<Uri, WeakReference> _cache = new Dictionary<Uri, WeakReference>();

        private Uri _source;

        public new Uri Source
        {
            get
            {
                if (!IsInDesignMode)
                {
                    return _source;
                }

                return base.Source;
            }

            set
            {
                if (!IsInDesignMode)
                {
                    _source = value;
                    if (!_cache.ContainsKey(_source))
                    {
                        AddToCache();
                    }
                    else
                    {
                        var weakReference = _cache[_source];
                        if (weakReference != null && weakReference.IsAlive)
                        {
                            MergedDictionaries.Add((ResourceDictionary)weakReference.Target);
                        }
                        else
                        {
                            AddToCache();
                        }
                    }
                }
                else
                {
                    base.Source = value;
                }
            }
        }

        private static bool IsInDesignMode
        {
            get
            {
                return
                    (bool)
                    DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(DependencyObject))
                                                .Metadata.DefaultValue;
            }
        }

        private void AddToCache()
        {
            base.Source = _source;
            if (_cache.ContainsKey(_source))
            {
                _cache.Remove(_source);
            }

            _cache.Add(_source, new WeakReference(this, false));
        }

#endif
    }
}